<template>
  <div class="game">
    <div class="time">时间：{{ dayjs(time * 1000).format("mm:ss") }}</div>
    <div class="sidebar">
      <div class="sidebar-item">网格类型：{{ range + " x " + range }}</div>
      <div class="sidebar-item">游戏难度：{{ level + "%" }}</div>
    </div>
    <div class="container">
      <div class="row" v-for="(item1, index1) in range" :key="index1">
        <div class="col" v-for="(item2, index2) in range" :key="index2">
          <Grid
            ref="ge"
            :x="index1"
            :y="index2"
            :isEnd="isEnd"
            @handleDfs="handleDfs"
            @judgeEnd="judgeEnd"
            @handleEnd="handleEnd"
            @addMine="addMine"
            @addComplete="addComplete"></Grid>
        </div>
      </div>
    </div>
    <el-dialog title="游戏结束" :visible.sync="dialogVisible" width="30%">
      <div class="dialogInfo">网格类型：{{ range + " x " + range }}</div>
      <div class="dialogInfo">游戏难度：{{ level + "%" }}</div>
      <div class="dialogInfo">用时：{{ dayjs(time * 1000).format("mm:ss") }}</div>
      <div class="dialogInfo">
        完成度：{{ ((complete * 100) / (range * range - mine)).toFixed(2) + "%" }}
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleNext()">再来一局</el-button>
        <el-button type="primary" @click="beginClickBg(), (dialogVisible = false)">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import dayjs from "dayjs";
import Grid from "./Grid.vue";
import { mapState, mapMutations } from "vuex";
export default {
  components: { Grid },
  data() {
    return {
      isEnd: false,
      time: 0,
      timer: null,
      dialogVisible: false,
      complete: 0,
      mine: 0,
    };
  },
  methods: {
    dayjs,
    ...mapMutations("record", ["addRecord"]),
    ...mapMutations("audio", ["beginClickBg"]),
    reset() {
      this.isEnd = false;
      this.time = 0;
      this.timer = null;
      this.complete = 0;
      this.mine = 0;
      let arr = this.$refs.ge;
      arr.forEach((item) => {
        item.reset();
      });
    },
    init() {
      let arr = this.$refs.ge;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].isMine) continue;
        for (let j = -1; j <= 1; j++) {
          for (let k = -1; k <= 1; k++) {
            if (
              arr[i].x + j < 0 ||
              arr[i].x + j >= this.range ||
              arr[i].y + k < 0 ||
              arr[i].y + k >= this.range
            )
              continue;
            if (arr[this.range * (arr[i].x + j) + arr[i].y + k].isMine) arr[i].value++;
          }
        }
      }
      this.timer = setInterval(() => {
        this.time++;
      }, 1000);
    },
    addComplete() {
      this.complete++;
    },
    addMine() {
      this.mine++;
    },
    handleDfs(x, y) {
      let idx = this.range * x + y;
      let arr = this.$refs.ge;
      if (arr[idx].isDfs) return;
      arr[idx].isDfs = true;
      if (!arr[idx].isMine) {
        arr[idx].handleClick();
        if (arr[idx].value == 0) {
          if (x - 1 >= 0) this.handleDfs(x - 1, y);
          if (x + 1 < this.range) this.handleDfs(x + 1, y);
          if (y - 1 >= 0) this.handleDfs(x, y - 1);
          if (y + 1 < this.range) this.handleDfs(x, y + 1);
          if (x - 1 >= 0 && y - 1 >= 0) this.handleDfs(x - 1, y - 1);
          if (x - 1 >= 0 && y + 1 < this.range) this.handleDfs(x - 1, y + 1);
          if (x + 1 < this.range && y - 1 >= 0) this.handleDfs(x + 1, y - 1);
          if (x + 1 < this.range && y + 1 < this.range) this.handleDfs(x + 1, y + 1);
        }
      }
    },
    addData() {
      let obj = {
        id: this.$store.state.record.len + 1,
        username: "玩家",
        gridType: this.range + " x " + this.range,
        gameLevel: this.level + "%",
        time: dayjs(this.time * 1000).format("mm:ss"),
        date: dayjs().format("YYYY-MM-DD HH:mm:ss"),
        complete: ((this.complete * 100) / (this.range * this.range - this.mine)).toFixed(2) + "%",
        isSuccess: this.complete == this.range * this.range - this.mine ? true : false,
      };
      this.addRecord(obj);
    },
    handleEnd() {
      this.isEnd = true;
      clearInterval(this.timer);
      if (this.recordFail) this.addData();
      setTimeout(() => {
        this.dialogVisible = true;
      }, 10);
    },
    judgeEnd() {
      let arr = this.$refs.ge;
      let flag = false;
      arr.forEach((item) => {
        if (!item.isMine && !item.flag) flag = true;
      });
      if (!flag) {
        this.isEnd = true;
        clearInterval(this.timer);
        this.addData();
        setTimeout(() => {
          this.dialogVisible = true;
        }, 10);
      }
    },
    handleNext() {
      this.beginClickBg();
      this.dialogVisible = false;
      this.reset();
      this.init();
    },
  },
  mounted() {
    this.init();
  },
  destroyed() {
    clearInterval(this.timer);
  },
  computed: {
    ...mapState("setting", ["range", "level", "recordFail"]),
  },
};
</script>

<style lang="less" scoped>
.game {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 1000px;
  height: 600px;
  margin: 0 auto;

  .time {
    position: fixed;
    top: 30px;
    right: 10%;
    font-size: 16px;
    color: red;
  }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 200px;
    // background: pink;
    padding: 20px;

    .sidebar-item {
      height: 40px;
      font-size: 16px;
      line-height: 40px;
      // background: cyan;
      color: #409eff;
    }
  }

  .container {
    display: flex;
    flex-direction: column;
    margin-top: 60px;

    .row {
      display: flex;
    }
  }

  /deep/ .el-dialog__body {
    padding-top: 5px;

    .dialogInfo {
      margin-top: 10px;
      // background: pink;
    }
  }
}
</style>
